home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
501-525
/
disk_502
/
cells
/
cellssource.lzh
/
cScreen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-20
|
10KB
|
409 lines
/*
* CELLS An Implementation of the WireWorld cellular automata
* as described in Scientific American, Jan 1990.
*
* Copyright 1990 by Davide P. Cervone.
* You may use this code, provided this copyright notice is kept intact.
* See the CELLS.HELP file for complete information on distribution conditions.
*/
/*
* File: cScreen.c Handles screen updates and scrolls.
*/
#include "Cells.h"
#undef INTUITION_PREFERENCES_H
#include <intuition/preferences.h>
#include <stdio.h>
#define COLORFILE "Cells.Colors"
#define WBCOLOR 0xFFFF
#define MAXLINE 132
extern UWORD GetRGB4();
/*
* ClearPatch()
*
* Clear the specified section of screen to the shadow color
* Draw the horizontal and vertical grid lines
*/
void ClearPatch(X,Y,W,H)
short X,Y,W,H;
{
register short i;
short x,y,w,h;
x = X * CellSize + BoardX + 1;
y = Y * CellSize + BoardY + 1;
w = W * CellSize + x - 2;
h = H * CellSize + y - 2;
SetAPen(rp,SHADOW);
RectFill(rp,x,y,w,h);
SetAPen(rp,GRID);
W += X; H += Y;
for (i=Y+1, Y=y+CellSize-1; i<H; i++,Y+=CellSize)
{
Move(rp,x,Y);
Draw(rp,w,Y);
}
for (i=X+1, X=x+CellSize-1; i<W; i++,X+=CellSize)
{
Move(rp,X,y);
Draw(rp,X,h);
}
}
/*
* ClearScreen()
*
* Clear the board area to backgound, then clear the grid to black
* Draw the border around the grid area
* Update the screen from the double buffer, if necessary.
*/
void ClearScreen(update)
int update;
{
SetDrMd(rp,JAM1);
SetAPen(rp,FOREGROUND);
RectFill(rp,0,0,BOARDW-1,BOARDH-1);
ClearPatch(0,0,GridW,GridH);
Move(rp,BoardX,BoardY);
Draw(rp,BoardX,BoardH+1);
Draw(rp,BoardW+1,BoardH+1);
Draw(rp,BoardW+1,BoardY);
Draw(rp,BoardX,BoardY);
if (update) UpdateScreen();
}
/*
* ScrollScreen()
*
* Scroll the grid area by the specified amount, clearing the new area
* If there was a move in the X direction, refresh the frame for that patch
* If there was a move in the Y direction, refresh the frame for that path
*/
void ScrollScreen(dx,dy)
short dx,dy;
{
register short x,y;
SetDrMd(rp,JAM1);
SetAPen(rp,BACKGROUND);
SetBPen(rp,SHADOW);
dx *= CellSize;
dy *= CellSize;
ScrollRaster(rp,dx,dy,BoardX,BoardY,BoardW+1,BoardH+1);
if (dx)
{
x = (dx < 0)? BoardX: BoardW+1;
Move(rp,x-dx,BoardY);
Draw(rp,x,BoardY);
Draw(rp,x,BoardH+1);
Draw(rp,x-dx,BoardH+1);
}
if (dy)
{
y = (dy < 0)? BoardY: BoardH+1;
Move(rp,BoardX,y-dy);
Draw(rp,BoardX,y);
Draw(rp,BoardW+1,y);
Draw(rp,BoardW+1,y-dy);
}
}
/*
* RefreshWithSelect()
*
* For each cell in the selected patch
* If we are moving or copying and the cell is selected
* set the pen according to whether the selection is being dragged or not
* Otherwise set the pen to the unselected cell color
* If the pen is not the blank color, refresh it on screen
* If we are selecing cells, and the cell is selected, and we are not
* moving or copying cells, draw a box around the cell
*/
void RefreshWithSelect(x,y,w,h,Grid)
short x,y,w,h;
UBYTE Grid[];
{
register short X,Y;
register short i;
register int Pen;
int MoveCopy = (MouseMoveType == MM_MOVE || MouseMoveType == MM_COPY);
for (Y=y; Y<y+h; Y++)
{
for (X=x, i=GridX+X+MAXGRIDW*(GridY+Y); X<x+w; X++,i++)
{
if (MoveCopy && CellSelected(i))
Pen = (SelectType == SEL_WAIT)? SELECTPEN: MOVEPEN;
else
Pen = Grid[i];
if (Pen != BLANK) ColorScreenCell(X,Y,Pen);
if (SelectType && NewGen[i] && MoveCopy == FALSE)
BoxCell(rp,X,Y,MOVEPEN);
}
}
}
/*
* RefreshNoSelect()
*
* For each cell in the selected patch
* if the cell is not blank, set the screen to that cell's color
*/
void RefreshNoSelect(x,y,w,h,Grid)
short x,y,w,h;
UBYTE Grid[];
{
register short X,Y;
register short i;
for (Y=y; Y<y+h; Y++)
{
for (X=x, i=GridX+X+MAXGRIDW*(GridY+Y); X<x+w; X++,i++)
if (Grid[i] != BLANK) ColorScreenCell(X,Y,Grid[i]);
}
}
/*
* RefreshPatch()
*
* Call the correct refresh routine on the selected patch
*/
void RefreshPatch(x,y,w,h,Grid)
short x,y,w,h;
UBYTE Grid[];
{
if (SelectType)
RefreshWithSelect(x,y,w,h,Grid);
else
RefreshNoSelect(x,y,w,h,Grid);
}
/*
* RefreshScreen()
*
* Refresh the entire visible grid area
*/
void RefreshScreen(Grid)
UBYTE Grid[];
{
RefreshPatch(0,0,GridW,GridH,Grid);
UpdateScreen();
}
/*
* RefreshSelect()
*
* For each cell in the visible area
* If the cell is selected
* set the pen color appropriately
* set the color of the cell on the screen
* if we are in select mode and the cell is selected and we are not moving
* or copying, box the selected cell
* refresh the screen from the double buffer
*/
void RefreshSelect(Grid)
UBYTE Grid[];
{
register short X,Y;
register short i;
register int Pen;
int MoveCopy = (MouseMoveType == MM_MOVE || MouseMoveType == MM_COPY);
int SelectPen = (SelectType == SEL_WAIT)? SELECTPEN: MOVEPEN;
for (Y=0; Y<GridH; Y++)
{
for (X=0, i=GridX+X+MAXGRIDW*(GridY+Y); X<GridW; X++,i++)
{
if (CellSelected(i))
{
if (MoveCopy) Pen = SelectPen; else Pen = Grid[i];
ColorScreenCell(X,Y,Pen);
if (SelectType && NewGen[i] && MoveCopy == FALSE)
BoxCell(rp,X,Y,MOVEPEN);
}
}
}
UpdateScreen();
}
/*
* Macros for dealing with colors, and the default color table
*/
#define BADVAL(c) ((c)<0||(c)>15)
#define COLOR(r,g,b) (((r)<<8)|((g)<<4)|(b))
#define RED(c) (((c)>>8)&0x0F)
#define GREEN(c) (((c)>>4)&0x0F)
#define BLUE(c) ((c)&0x0F)
static UWORD Color[] =
{
COLOR( 4, 6, 5), /* background color */
COLOR(14,15,12), /* highlight color */
COLOR( 8,10, 8), /* foreground color */
COLOR( 0, 3, 2), /* shadow color */
COLOR(15,12, 9), /* TAIL color */
COLOR(15, 9, 0), /* HEAD color */
COLOR( 9, 6, 1), /* inverted button color */
COLOR( 0,10, 0), /* WIRE color */
};
static UWORD PointerColor;
/*
* COlorVal()
*
* Convert a hexadecimal character into an integer value
*/
static short ColorVal(c)
char c;
{
short color;
if (c >= '0' && c <= '9')
color = c - '0';
else if (c >= 'A' && c <= 'F')
color = c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
color = c - 'a' + 10;
else color = 16; /* an illegal value */
return(color);
}
/*
* ReadColorFile()
*
* Open the color file, if it exists
* while there are more colors to read, and more lines in the file
* if we can read the next line in the file
* if there is something on the line to be considered
* if command is '=' (use workbench color) indicate that
* otherwise if the command is not '*' (use default color)
* get the RGB values from the line
* give an error if any is no good, and record them if all OK
* go on to the next color
* otherwise
* warn about problems reading the file
* if there are additional lines to read after all the colors are
* read in, indicate that they are being ignored
* close the file
*/
void ReadColorFile()
{
FILE *InFile;
char Line[MAXLINE];
short i = 0;
short R,G,B;
InFile = fopen(COLORFILE,"r");
if (InFile)
{
while (i<(1<<SCREEND) && !feof(InFile))
{
if (fgets(Line,MAXLINE-1,InFile))
{
if (Line[0] && Line[0] != ' ' && Line[0] != '\n')
{
if (Line[0] == '=')
{
Color[i] = WBCOLOR;
} else if (Line[0] != '*') {
R = ColorVal(Line[0]);
G = ColorVal(Line[1]);
B = ColorVal(Line[2]);
if (strlen(Line) < 4 || BADVAL(R) || BADVAL(G) || BADVAL(B))
printf("Invalid Color: %s",Line);
else
Color[i] = COLOR(R,G,B);
}
i++;
}
} else {
printf("Unexpected End of Color File\n");
}
}
if (fgets(Line,MAXLINE,InFile))
printf("Extra Lines in Color File Ignored\n");
fclose(InFile);
}
}
/*
* LoadColors()
*
* For every color in the table that was supposed to come from the workbench
* set the color table to that color
* Set the screen's color table
* Read the preferences setting for the pointer's standard color
*/
void LoadColors()
{
struct Preferences thePreferences;
short i;
short Depth = 1 << myScreen->BitMap.Depth;
for (i=0; i<Depth; i++)
if (Color[i] == WBCOLOR)
Color[i] = GetRGB4(myScreen->ViewPort.ColorMap,i);
LoadRGB4(&(myScreen->ViewPort),&Color[0],Depth);
GetPrefs(&thePreferences,sizeof(struct Preferences));
PointerColor = thePreferences.color18;
}
/*
* SetPointerColor()
*
* Set the screen's pointer color to the indicated color values for the
* specified color in the color table
*/
void SetPointerColor(i)
short i;
{
SetRGB4(&(myScreen->ViewPort),POINTERPEN,
RED(Color[i]),GREEN(Color[i]),BLUE(Color[i]));
}
/*
* RestorePointerColor()
*
* Set the pointer color to the default preferences color
*/
void RestorePointerColor()
{
SetRGB4(&(myScreen->ViewPort),POINTERPEN,
RED(PointerColor),GREEN(PointerColor),BLUE(PointerColor));
}